package myJs.register

import myJs.api.Api
import myJs.myPkg.yup._

import scala.collection.mutable
import scala.concurrent.Future
import scala.scalajs.js
import org.scalajs.macrotaskexecutor.MacrotaskExecutor.Implicits._
import shared.pojo.Pojo.{EmailData, Login, PhoneData, UserNameData}

import scala.scalajs.js.JSConverters._
import scala.scalajs.js.Promise

/**
 * Created by yz on 7/12/2022
 */
object Schema {

  case class ValidInfo(v: String, valid: Boolean)

  val cacheMap = mutable.SeqMap[String, ValidInfo]()

  def cacheTest(key: String)(f: String => Future[Boolean]) = (v: String) => {
    val beforeV = cacheMap.getOrElse(key, ValidInfo("", true))
    if (beforeV.v != v) {
      f(v).map { x =>
        cacheMap.put(key, ValidInfo(v, x))
        x
      }.toJSPromise
    } else {
      Future {
        beforeV.valid
      }.toJSPromise
    }
  }

  def nameValidateF(key: String) = cacheTest(key) { v: String =>
    val request = UserNameData(name = v)
    Api.userNameCheck(request).map { response =>
      response.valid
    }
  }

  def emailValidateF(key: String) = cacheTest(key) { v: String =>
    val request = EmailData(email = v)
    Api.emailCheck(request).map { response =>
      response.valid
    }
  }


  def phoneValidateF(key: String) = cacheTest(key) { v: String =>
    val request = PhoneData(phone = v)
    Api.phoneCheck(request).map { response =>
      response.valid
    }
  }

  def captchaValidateF = (v: String, context: TestContext) => {
    val code = context.parent("code")
    code.toLowerCase == v.toLowerCase
  }

  val schema = Yup.`object`().shape(js.Dictionary(
    "name" -> Yup.string().required("用户名不能为空！")
            .test(name = "nameCheck", message = "用户名已存在！", test = nameValidateF("name"))
      .matches(regex = js.RegExp("^[^@@]*[^\\d@@]+[^@@]*$"), message = "用户名不能为纯数字且不能含有@@！"),
    "fullName" -> Yup.string().required("姓名不能为空！"),
    "unit" -> Yup.string().required("单位不能为空！"),
    "email" -> Yup.string().required("邮箱不能为空！")
      .email("邮箱不合法！")
      .test(name = "emailCheck", message = "邮箱已注册！", test = emailValidateF("email")),
    "phone" -> Yup.string().required("手机不能为空！")
      .matches(regex = js.RegExp("^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\\d{8}$"),
        message = "手机不合法！")
          .test(name = "phoneCheck", message = "手机已注册！", test = phoneValidateF("phone")),
    "password" -> Yup.string().required("密码不能为空！")
      .matches(regex = js.RegExp("^(?=\\w*\\d)(?=\\w*[A-Z])(?=\\w*[a-z])[\\w]{6,}$"),
        message = "密码只能由数字和字母组成，必须同时包含大小写，且不小于6位！"),
    "confirmPassword" -> Yup.string().required("确认密码不能为空！")
      .oneOf(enums = js.Array(Yup.ref("password")),
        message = "两次密码不一样!"),
    "captcha" -> Yup.string().required("验证码不能为空！")
          .test(name = "checkCaptcha", message = "验证码错误！", test = captchaValidateF),
  ))
}
